package com.xpec.c4.service.utility;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.xpec.c4.game.utility.GUID;
import com.xpec.c4.persistence.PersistenceManager;
import com.xpec.c4.service.common.ServiceConfig;
import com.xpec.c4.service.module.common.PlayerCommonInfoManager;

/**
 * 
 * 
 * @author Bany
 * 
 * @since 2008-11-27 下午06:47:25
 * 
 */

public class Utility {

	/**
	 * 
	 */
	private static final String CONFIG_DIR = "config/";
	/**
	 * 类型映射的表
	 */
	private static Map<Class<?>, Class<?>> clazzTypeMapping = new HashMap<Class<?>, Class<?>>();
	
	/**
	 * sessionID与IP的对应表
	 */
	private static Map<String,String> sessionIPMapping = Collections.synchronizedMap(new WeakHashMap<String, String>(5000));

	static {
		clazzTypeMapping.put(Integer.class, int.class);
		clazzTypeMapping.put(Long.class, long.class);
		clazzTypeMapping.put(Boolean.class, boolean.class);
		clazzTypeMapping.put(Short.class, short.class);
		clazzTypeMapping.put(Float.class, float.class);
		clazzTypeMapping.put(Double.class, double.class);
		clazzTypeMapping.put(Character.class, char.class);
		clazzTypeMapping.put(Byte.class, byte.class);
	}

	/**
	 * 得到布尔型的字节
	 * 
	 * @param bol
	 * @return
	 */
	public static Byte getBoolean(boolean bol) {
		return bol == true ? Byte.valueOf("1") : Byte.valueOf("0");
	}

	/**
	 * 从buffer得到boolean值
	 * 
	 * @param theMessage
	 * @return
	 */
	public static boolean getBoolean(ByteBuffer theMessage) {
		byte b = theMessage.get();
		return b == 1 ? true : false;
	}

	/**
	 * 类型映射查找<br>
	 * 
	 * @param clazz
	 *            待查找的映射类型
	 * @return 查找的结果。如果查找到映射类型，则返回查询得到的类型；如果没有查找到，则返回原来的类型
	 */
	public static Class<?> getMappingClass(Class<?> clazz) {
		Class<?> mappingClazz = clazzTypeMapping.get(clazz);
		if (mappingClazz != null) {
			return mappingClazz;
		}
		return clazz;
	}

	private static void initPersistenceSystem() {
		String editorResourceRootPath = "EditorReSource/xml/";
		String projectPath = ServiceConfig.rootPath + "/";
		editorResourceRootPath = projectPath + editorResourceRootPath;
		System.out.println(editorResourceRootPath);

		PersistenceManager pm = PersistenceManager.getInstance();
		pm.init(editorResourceRootPath);
		System.out.println("init xml");
	}

	public static void persistenceSave(Object pObject, String pFileName,
			String pEcodingType) {
		try {
			initPersistenceSystem();
			PersistenceManager pm = PersistenceManager.getInstance();
			Document doc = null;

			doc = DocumentBuilderFactory.newInstance().newDocumentBuilder()
					.newDocument();
			Element root = (Element) pm.build(pObject);
			doc.adoptNode(root);
			doc.appendChild(root);
			doc.setXmlStandalone(true);
			TransformerFactory tf = TransformerFactory.newInstance();
			tf.setAttribute("indent-number", new Integer(4));
			Transformer transformer = tf.newTransformer();
			DOMSource source = new DOMSource(doc);
			StreamResult result = new StreamResult(new BufferedWriter(
					new OutputStreamWriter(new PrintStream(
							new FileOutputStream(new File(pFileName)), true,
							pEcodingType))));
			transformer.setOutputProperty("indent", "yes");
			transformer.setOutputProperty("encoding", "UTF-8");

			transformer.transform(source, result);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 从XML读取对象
	 * 
	 * @param pFileName
	 *            要读的XML文件名
	 * @param pObjectToFillIn
	 *            待填充对象，如果不为null，则会将数据填充到objToFillIn中
	 * @return
	 */
	public static Object persistenceLoad(String pFileName,
			Object pObjectToFillIn) {
		try {
			initPersistenceSystem();
			PersistenceManager pm = PersistenceManager.getInstance();
			Document doc = null;
			doc = DocumentBuilderFactory.newInstance().newDocumentBuilder()
					.parse(new java.io.File(pFileName));
			return pm.parse(pObjectToFillIn, doc.getDocumentElement());
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 获得文件的流数据
	 * 
	 * @param filename
	 * @return
	 * 
	 * @author lipeilin
	 * @2011-7-6 下午06:45:26
	 */
	public static InputStream getFileInputStream(String filename) {

		String basePath = System.getProperty("user.dir");
		String separator = System.getProperty("file.separator");
		String configPath = basePath + separator + CONFIG_DIR + separator;

		InputStream is = null;

		//
		// classes
		if (Utility.class.getClassLoader().getResource("") != null) {
			String realPath = Utility.class.getClassLoader().getResource("")
					.getPath();
			realPath += (filename);
			try {
				is = new FileInputStream(realPath);
				if (is != null) {
					System.out.println("getFileInputStream: " + realPath);
					return is;
				}
			} catch (FileNotFoundException e) {
			}

		}
		//
		is = Utility.class.getResourceAsStream(filename);
		if (is != null) {
			URL url = Utility.class.getResource(filename);
			System.out.println("getFileInputStream: " + url);
			return is;
		}

		//
		try {
			is = new FileInputStream(configPath + filename);
			if (is != null) {
				System.out.println("getFileInputStream: " + configPath
						+ filename);
				return is;
			}
		} catch (FileNotFoundException e) {
		}

		//
		is = Utility.class.getClassLoader().getResourceAsStream(filename);
		if (is != null) {
			URL url = Utility.class.getClassLoader().getResource(filename);
			System.out.println("getFileInputStream: " + url);
			return is;
		}

		//
		try {
			is = new FileInputStream(filename);
			if (is != null) {
				System.out.println("getFileInputStream: " + filename);
				return is;
			}
		} catch (FileNotFoundException e) {
		}

		//
		System.err.println("getFileInputStream: " + filename + " not found!!");
		return null;

		// InputStream is = Utility.class.getResourceAsStream(filename);
		// if (is == null) {
		// is = Utility.class.getClassLoader().getResourceAsStream(filename);
		// }
		// if (is == null) {
		// try {
		// is = new FileInputStream(filename);
		// } catch (FileNotFoundException e) {
		// }
		// }
		// if (is == null) {
		// try {
		// is = new FileInputStream(configPath + filename);
		// } catch (FileNotFoundException e) {
		// }
		// }
		// return is;
	}

	/**
	 * 获得文件的流数据
	 * 
	 * @param filename
	 * @return
	 * 
	 * @author lipeilin
	 * @2011-7-6 下午06:45:26
	 */
	public static URL getUrl(String filename) {
		String realPath = null;
		File file = null;
		URL url = null;

		// classes
		if (Utility.class.getClassLoader().getResource("") != null) {
			realPath = Utility.class.getClassLoader().getResource("").getPath();
			realPath += (filename);
			file = new File(realPath);
			try {
				if (file.exists()) {
					System.out.println(file.toURI().toURL());
					return file.toURI().toURL();
				}
			} catch (MalformedURLException e) {
				e.printStackTrace();
			}
		}

		// config
		String basePath = System.getProperty("user.dir");
		String separator = System.getProperty("file.separator");
		String configPath = basePath + separator + CONFIG_DIR + separator;

		realPath = configPath + filename;
		file = new File(realPath);
		try {
			if (file.exists()) {
				System.out.println(file.toURI().toURL());
				return file.toURI().toURL();
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}

		//
		url = ClassLoader.getSystemResource(filename);
		if (url != null) {
			System.out.println(url);
			return url;
		}

		// 若是jar檔, 找找jar檔裡面的設定
		url = Utility.class.getClassLoader().getResource(filename);
		if (url != null) {
			System.out.println(url);
			return url;
		}

		System.err.println(filename + " not found!!");
		return null;

	}
	
	/**
	 * 通过sessionID，获得其中的IP数据
	 * @param sessionID
	 * @return
	 */
	public static String getIpBySessionID(GUID sessionID){
		if(sessionID == null){
			return null;
		}
		
		return PlayerCommonInfoManager.getInstance().getClientIpBySessionId(sessionID);
		
//		String ip = sessionIPMapping.get(sessionID);
//		
//		//缓存有，就从缓存取
//		if(ip != null){
//			return ip;
//		}
//		
//		int begin = sessionID.indexOf("/");
//		int end = sessionID.indexOf(":");
//		
//		if(begin < 0){
//			begin = sessionID.indexOf("#");
//		}
//		
//		if(end < 0){
//			end = sessionID.length();
//		}
//		ip = sessionID.substring(begin+1,end);
//		
//		sessionIPMapping.put(sessionID, ip);
//		
//		return ip;
	}
	
	public static String readTextFile(String filePath) {
		File file = new File(filePath);
		StringBuffer contents = new StringBuffer();
		BufferedReader reader = null;

		try {
			reader = new BufferedReader(new FileReader(file));
			String text = null;

			// repeat until all lines is read
			while ((text = reader.readLine()) != null) {
				contents.append(text).append(
						System.getProperty("line.separator"));
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (reader != null) {
					reader.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		// show file contents here
		// logger.debug(contents.toString());
		return contents.toString();
	}

	public static void main(String[] args) throws IOException {

		InputStream is = getFileInputStream("group.properties");
		System.out.println(is + " size : " + is.available());
		is = getFileInputStream("abc.txt");
		System.out.println(is + " size : " + is.available());

		URL url = getUrl("group.properties");
		System.out.println(url + " exist :" + url.openStream().available());
		url = getUrl("abc.txt");
		System.out.println(url + " exist :" + url.openStream().available());
	}
	
	public static String readFully(InputStream inputStream, String encoding)
	        throws IOException {
	    ByteArrayOutputStream baos = new ByteArrayOutputStream();
	    byte[] buffer = new byte[1024];
	    int length = 0;
	    while ((length = inputStream.read(buffer)) != -1) {
	        baos.write(buffer, 0, length);
	    }
	    return new String(baos.toByteArray(), encoding);
	}

}
